<?php

namespace app\utils;

use Illuminate\Support\Arr;

class ArrayUtil
{
    /**
     * @param $array
     * @return array
     * 将数组中的.替换为->
     */
    public static function replaceDotWithArrow($array): array
    {
        $newArray = [];

        $array = Arr::dot($array);

        foreach ($array as $key => $value) {
            $newKey = str_replace('.', '->', $key);
            if (is_array($value)) {
                $newValue = self::replaceDotWithArrow($value);
            } else {
                $newValue = $value;
            }
            $newArray[$newKey] = $newValue;
        }

        return $newArray;
    }

    /**
     * @param array $firstArr
     * @param string $firstArrKey
     * @param array $secondArr
     * @param string $secondArrKey
     * @param bool $isUnique
     * @return array
     * 对比两个二维数组中的值，返回不同的值
     */
    public static function getDoubleArrayDiff(
        array $firstArr,
        string $firstArrKey,
        array $secondArr,
        string $secondArrKey,
        bool $isUnique = true
    ): array {
        $first = $second = [];

        if (count(explode('.', $firstArrKey)) == 2) {
            foreach ($firstArr as $value) {
                $first[] = Arr::get($value, $firstArrKey);
            }
        } else {
            $first = array_column($firstArr, $firstArrKey);
        }

        if (count(explode('.', $secondArrKey)) == 2) {
            foreach ($secondArr as $value) {
                $second[] = Arr::get($value, $secondArrKey);
            }
        } else {
            $second = array_column($secondArr, $secondArrKey);
        }

        if ($isUnique) {
            $first = array_unique($first);
            $second = array_unique($second);
        }

        return array_diff($first, $second);
    }

    /**
     * @param array $array
     * @return string
     * 计算数组中的值的和, 保留精度
     */
    public static function arrayBcAdd(array $array)
    {
        $result = '0.00';

        array_walk($array, function ($item) use (&$result) {
            $result = bcadd($result, $item, 2);
        });

        return $result;
    }

    /**
     * @param string $startDate - 开始日期
     * @param int $delayWeeks - 延期周数
     * @return array
     * 生成延期周数的日期数组
     */
    public static function generateDelayedWeekdays(string $startDate, int $delayWeeks): array
    {
        $result = [];

        for ($i = 1; $i <= $delayWeeks; $i++) {
            $result[] = date('Y-m-d', strtotime($startDate . ' +' . $i . ' week'));
        }

        return $result;
    }

    /**
     * @param array $array
     * @param string $keyToRemove
     * @param mixed $valueToRemove
     * @return array
     * 删除二维数组中的某个键
     */
    public static function removeElementByKeyValue(array &$array, string $keyToRemove, mixed $valueToRemove): array
    {
        foreach ($array as $index => &$subArray) {
            if (array_key_exists($keyToRemove, $subArray) && $subArray[$keyToRemove] === $valueToRemove) {
                unset($array[$index]);
            }
        }

        return array_values($array);
    }

    public static function onlyNotEmpty(array $array, string|array $onlyKeys): array
    {
        return Arr::only(
            array_filter($array, function ($v) {
                return !empty($v);
            }),
            $onlyKeys
        );
    }

    /**
     * @param array $data
     * @param array $flatData
     * @return void
     * 递归将树形结构扁平化为二维数组
     */
    public static function flattenTree(array $data, array &$flatData = []): void
    {
        foreach ($data as $node) {
            $nodeData = $node;
            unset($nodeData['children']);
            $flatData[] = $nodeData;

            if (!empty($node['children'])) {
                self::flattenTree($node['children'], $flatData);
            }
        }
    }

    /**
     * @param array $array1
     * @param array $array2
     * @return array
     * 获取两个一维数组的笛卡尔积
     */
    public static function getCrossJoinArray(array $array1, array $array2): array
    {
        $result = [];

        foreach ($array1 as $item1) {
            foreach ($array2 as $item2) {
                $result[] = [$item1, $item2];
            }
        }

        return $result;
    }

    /**
     * 深提取数组中的字段
     * @param array $array
     * @param array $fields
     * @param mixed|null $default
     * @return mixed
     */
    public static function extractField(array $array, array $fields, mixed $default = ''): mixed
    {
        foreach ($fields as $key) {
            if (is_array($array) && isset($array[$key])) {
                $array = $array[$key];
            } else {
                return $default;
            }
        }

        return $array;
    }

}
